#include "ThreadQueue.h"
#include "Event.h"
#include "Util.h"

namespace qy
{

ThreadQueue::ThreadQueue(int conThreadCount)
: m_conThreadCount(conThreadCount)
{
    pthread_mutex_init(&m_threadsMutex, NULL);
	m_loopEvent = Event::create();
}

ThreadQueue::~ThreadQueue()
{
    pthread_mutex_destroy(&m_threadsMutex);
	Event::destroy(m_loopEvent);
	m_loopEvent = NULL;
}

int ThreadQueue::run()
{
    while(!m_stop)
	{
	    for(std::list<Thread*>::iterator it = m_workingThreads.begin(); it != m_workingThreads.end();)
		{
		    if((*it)->isRunning() == false)
			{
			    it = m_workingThreads.erase(it);
			}
			else
			{
			    it++;
			}
		}

	    pthread_mutex_lock(&m_threadsMutex);
		while(m_conThreadCount >  m_workingThreads.size())
		{
		    if(m_waitingThreads.size() == 0)
			{
			    break;
			}

			Thread *pThread = m_waitingThreads.front();
			pThread->setFinishedEvent(m_loopEvent);
			pThread->start();
			m_workingThreads.push_back(pThread);
			m_waitingThreads.pop();
		}
	    pthread_mutex_unlock(&m_threadsMutex);
		m_loopEvent->wait();
	}
}

void ThreadQueue::addThread(Thread *pThread)
{
    pthread_mutex_lock(&m_threadsMutex);
	m_waitingThreads.push(pThread);
	pthread_mutex_unlock(&m_threadsMutex);
	if(m_loopEvent)
	{
		m_loopEvent->post();
	}
}

}
